# -*- coding:utf-8 -*-
"""
@Author : 审心
@Time : 2023/3/22 15:28
"""
import logging
import os
from io import StringIO
from logging import Logger
from typing import Tuple

from colorama import init, Fore, Style

from common.logger.error import LogFileFlushError

# 初始化 colorama 库
init()
logger_format = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')


class MemoryHandler(logging.Handler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.buffer = StringIO()

    def emit(self, record):
        msg = self.format(record)
        self.buffer.write(msg + '\n')

    def get_log_content(self):
        return self.buffer.getvalue()


def create_logger(name: str, is_create_file: bool = False, filename: str = 'default.log') -> tuple[
    Logger, MemoryHandler]:
    """
    创建 logger 对象
    :rtype: logging.Logger
    :param name 日志对象名称
    :param is_create_file 是否创建日志文件
    :param filename 日志文件名称
    :return: logger 对象
    """
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)
    # 创建带颜色的控制台日志处理器
    color_console_handler = ColorizingStreamHandler()
    color_console_handler.setLevel(logging.DEBUG)
    # 创建带颜色的控制台日志格式化器
    color_console_formatter = logger_format
    # 将格式化器添加到处理器中
    color_console_handler.setFormatter(color_console_formatter)
    # 将处理器添加到 logger 对象中
    logger.addHandler(color_console_handler)
    if is_create_file:
        create_file_log(filename, logger)
    # 加了这几行，获取日志内容
    memory_handler = MemoryHandler()
    memory_handler.setLevel(logging.DEBUG)
    memory_handler.setFormatter(color_console_formatter)
    logger.addHandler(memory_handler)
    return logger, memory_handler


def create_file_log(file_path: str, logger: logging.Logger):
    """
    创建日志文件
    :param file_path: 日志文件存储路径
    :param logger 日志对象
    :return: 文件处理对象
    """
    if os.path.exists(file_path):
        os.remove(file_path)
    file_handler = logging.FileHandler(file_path, mode='a', encoding='utf-8')
    file_handler.setLevel(logging.DEBUG)
    file_handler.setFormatter(logger_format)
    logger.addHandler(file_handler)
    return file_handler


def flush_file_log(logger: logging.Logger, file_handler: logging.FileHandler, is_remove: bool = False,
                   is_reset: bool = False):
    """
    直接输出日志文件
    :param logger 当前使用的日志对象
    :param file_handler 日志文件处理器
    :param is_remove 是否删除本地日志文件
    :param is_reset 是否重新设置一个日志处理器
    :return: is_reset ? 新的日志文件对象 : None
    """
    if file_handler in logger.handlers:
        file_handler.flush()
        logger.removeHandler(file_handler)
        file_handler.close()
        logging.shutdown()
    else:
        raise LogFileFlushError(
            f"传入的 logger : {logger.name} 无法操作不包含 传入的 file_handler : {file_handler.baseFilename}")
    if is_remove:
        os.remove(file_handler.baseFilename)
    if is_reset:
        return create_file_log(file_handler.baseFilename, logger)
    else:
        return None


def clear_file_log(file_path: str, logger: logging.Logger = None, is_close_file: bool = False,
                   is_remove_file: bool = False):
    """
    清空日志文件内容
    :param file_path 日志文件存储路径
    :param logger 日志对象用于关闭 处理器
    :param is_close_file 是否关闭对日志文件的输出
    :param is_remove_file 是否删除日志文件
    """
    with open(file_path, mode='w', encoding='utf-8') as f:
        f.truncate(0)
    if logger is not None:
        for handler in logger.handlers:
            if is_close_file and isinstance(handler, logging.FileHandler):
                logger.removeHandler(handler)
                handler.close()
    if is_remove_file:
        try:
            os.remove(file_path)
            print(f"{file_path} has been deleted successfully!")
        except OSError as error:
            print(f"Error: {file_path} cannot be deleted. {error}")


def clear_console():
    """
    清空控制台信息
    :return:
    """
    if os.name == 'nt':
        os.system('cls')
    else:
        os.system('clear')


# 创建带颜色的控制台日志处理器
class ColorizingStreamHandler(logging.StreamHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.color_map = {
            logging.DEBUG: Fore.BLUE,
            logging.INFO: Fore.GREEN,
            logging.WARNING: Fore.YELLOW,
            logging.ERROR: Fore.RED,
        }

    def emit(self, record):
        try:
            message = self.format(record)
            self.stream.write(self.color_map[record.levelno] + message + Style.RESET_ALL + '\n')
            self.flush()
        except Exception:
            self.handleError(record)


log_, memory_handler = create_logger('default')
global_log_file = create_file_log(
    os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + '//global.log', log_)

if __name__ == '__main__':
    log_.info(f"日志文件名称 {global_log_file.name, global_log_file.baseFilename}")
    log_.debug(f"debug : {'芜湖'}")
    log_.info(f"info : {'起飞'}")
    log_.error(f"error : {123}")
    log_.warning(f"warn : {123}")
    # clear_file_log("test.log", log_, True, True)
    flush_file_log(log_, global_log_file, is_remove=True)
    log_.warning(f"清空日志完毕 : {123}")
